Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add RETURNDATACOPY and RETURNDATASIZE to assembly (and LLL) #2275

Merged
merged 8 commits into from
Jun 13, 2017

Conversation

pirapira
Copy link
Member

This PR adds RETURNDATACOPY and RETURNDATASIZE in LLL so that Metropolis tests in etheruem/tests can be developed more easily. In passing, I added minimum documentation and tests about inline assembly.

@axic axic changed the title Add RETURNDATACOPY and RETURNDATASIZE in LLL Add RETURNDATACOPY and RETURNDATASIZE to assembly (and LLL) May 17, 2017
@@ -49,6 +49,8 @@ enum class Instruction: uint8_t
MULMOD, ///< unsigned modular multiplication
EXP, ///< exponential operation
SIGNEXTEND, ///< extend length of signed integer
RETURNDATASIZE = 0xd, ///< get size of the last return data
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We've agreed to a different opcode on the last call.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the info. I'll update my yellow paper PR, the test PR and this one.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I moved them to 0x3d and 0x3e.

@@ -182,6 +182,10 @@ In the grammar, opcodes are represented as pre-defined identifiers.
+-------------------------+------+-----------------------------------------------------------------+
| signextend(i, x) | | sign extend from (i*8+7)th bit counting from least significant |
+-------------------------+------+-----------------------------------------------------------------+
| returndatasize | | size of the last return data |
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please move this to the right location after the opcode is updated.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done.

@@ -174,6 +174,16 @@ BOOST_AUTO_TEST_CASE(list)
BOOST_CHECK(!successParse("()"));
}

BOOST_AUTO_TEST_CASE(returndatacopy)
{
BOOST_CHECK(successParse("( returndatacopy 0 1 2 )"));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not think there's a need for parser test. The parser doesn't care.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree. The test succeeded even before the change. So this does not add any value.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So I removed this test and the next similar one.

BOOST_AUTO_TEST_CASE(returndatasize_can_be_compiled)
{
char const* sourceCode = R"(
(returnlll
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure this is needed (though probably cannot hurt), because LLL just exposes every single opcode. Potentially we should test for every single one? :)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was the motivation of the whole PR.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But we do not test for 99% of the opcodes.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let me see if there is any other opcode tested this way.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, I can guess from the other tests that opcodes are visible. I see sstore, codecopy, mstore8, div, exp and so on. So I don't need this test.

Copy link
Member

@axic axic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please update the opcode.

@axic
Copy link
Member

axic commented May 17, 2017

It is also missing the changelog entry and the optimiser changes (GasMeter, SemanticInformation).

@pirapira
Copy link
Member Author

I think I updated everything.

@@ -203,6 +205,8 @@ static const std::map<Instruction, InstructionInfo> c_instructionInfo =
{ Instruction::GASPRICE, { "GASPRICE", 0, 0, 1, false, Tier::Base } },
{ Instruction::EXTCODESIZE, { "EXTCODESIZE", 0, 1, 1, false, Tier::ExtCode } },
{ Instruction::EXTCODECOPY, { "EXTCODECOPY", 0, 4, 0, true, Tier::ExtCode } },
{ Instruction::RETURNDATASIZE, {"RETURNDATASIZE", 0, 0, 1, false, Tier::Base } },
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indentation is wrong here

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed.

scripts/tests.sh Outdated
@@ -71,9 +71,9 @@ sleep 2
# And then run the Solidity unit-tests (once without optimization, once with),
# pointing to that IPC endpoint.
echo "--> Running tests without optimizer..."
"$REPO_ROOT"/build/test/soltest --show-progress -- --ipcpath /tmp/test/geth.ipc && \
"$REPO_ROOT"/build/test/soltest --show-progress -t '*/returndata*' -- --ipcpath /tmp/test/geth.ipc && \
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't filter for returndata here :)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, sorry. This change is garbage.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reverted these changes.

@axic axic force-pushed the returndata_lll branch 5 times, most recently from 9e414af to 1bfae8d Compare May 24, 2017 13:04
@@ -232,6 +232,10 @@ In the grammar, opcodes are represented as pre-defined identifiers.
+-------------------------+------+-----------------------------------------------------------------+
| extcodecopy(a, t, f, s) | `-` | like codecopy(t, f, s) but take code at address a |
+-------------------------+------+-----------------------------------------------------------------+
| returndatasize | | size of the last return data |
+-------------------------+------+-----------------------------------------------------------------+
| returndatacopy(t, f, s) | `*` | copy s bytes from returndata at position f to mem at position t |
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Either we should call it returndataor return data in both places.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right.

@axic
Copy link
Member

axic commented May 24, 2017

I think we should have warnings in place if using these Metropolis instructions. This applies to CREATE and STATICCALL too.

@axic
Copy link
Member

axic commented May 24, 2017

Added warnings to the analyzer, will push it later the evening.

@chriseth
Copy link
Contributor

Please add a warning if in the scope of an inline assembly block there is a solidity identifier called returndatasize.

@@ -429,6 +429,16 @@ BOOST_AUTO_TEST_CASE(revert)
BOOST_CHECK(successAssemble("{ revert(0, 0) }"));
}

BOOST_AUTO_TEST_CASE(returndatasize)
{
BOOST_CHECK(successAssemble("{ let r := returndatasize }"));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also potentially this should be in "functional notation" to be in line with returndatacopy / revert.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is an exception that for an opcode x, if x() is valid, you can omit the parentheses. We could make that more strict (it is more strict in julia already).

Copy link
Member

@axic axic May 24, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both are valid, it is only about consistency:

  • do not test for these
  • test with one notation only (but use the same for these "opcode tests")
  • test with both notations (this has its own merits, given the code paths in the parser/analyzer are different)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should test random styles on random instructions to catch different kinds of errors. I don't think we get coverage efficiently if we tested the same set of styles for all instructions.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we want to catch as many bugs as possible we should test for both notations.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But, if no other instruction is tested for "both styles", maybe now is a good time to do that for at least one instruction.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is the opposite, practically no "functional instructions" are tested in the assembler section.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add is already tested for both styles in functional, but it has two arguments: not zero or three.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You have to look at the SolidityInlineAssembler/Analysis suite. The others don't assemble.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, and at this point, it's easier to add both styles.

case solidity::Instruction::RETURNDATACOPY:
m_errors.push_back(make_shared<Error>(
Error::Type::Warning,
"The RETURNDATASIZE/RETURNDATACOPY instructions are only available after "
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any better suggestion for wording?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@pirapira @chriseth can you please review this?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't STATICCALL belong here?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And CREATE2 (and REVERT with a different message), but those are not merged yet.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

STATICCALL has already been merged.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is pending as #2192?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I was seeing cpp-ethereum. Sorry.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@chriseth @pirapira this is the main question in this PR though: what wording do we go with 😉

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks perfect to me. It should be a warning, it should mention Metropolis, and it should tell this and that instructions will become available with Metropolis.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

{
string instructionName{instruction.first}; // needs to copy because making it lower case.
boost::algorithm::to_lower(instructionName);
auto declarations = nameFromCurrentScope(instructionName);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you test whether this always reports the global sha3?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, that might be happening; there might be a warning about sha3 on every possible source code with inline assembly. I should add a test about that.

solAssert(!!declaration, "");
m_errorReporter.warning(
declaration->location(),
"Variable is shadowed in an inline assembly by an insturction of the same name"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"in an" -> "in" and "instruction" -> "instruction"?

pirapira added a commit that referenced this pull request Jun 13, 2017
pirapira added a commit that referenced this pull request Jun 13, 2017
@chriseth
Copy link
Contributor

Please merge when tests are green.

@axic
Copy link
Member

axic commented Jun 13, 2017

Can you please squash some commits? The "fix typo" commit only fixed the code and there will be another one fixing the tests 😉

Could be merged into the original commit.

@pirapira
Copy link
Member Author

@axic squashed a bit.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants